package com.ljl.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson.JSONObject;
import com.ljl.entity.Account;
import com.ljl.entity.SignInLog;
import com.ljl.exception.BadRequestException;
import com.ljl.repository.AccountRepository;
import com.ljl.service.AccountService;
import com.ljl.service.FytxService;
import com.ljl.service.SignInLogService;
import com.ljl.service.dto.AccountQueryCriteria;
import com.ljl.service.dto.SignInResultDto;
import com.ljl.util.PageUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author 刘家良
 * @date 2022/09/10 23:38
 * @description
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AccountServiceImpl implements AccountService {

    private final AccountRepository accountRepository;
    private final FytxService fytxService;
    private final SignInLogService signInLogService;

    @Override
    public JSONObject signInByAccountId(Long accountId) {
        JSONObject res = new JSONObject();
        Account account = accountRepository.findById(accountId).orElseGet(Account::new);
        if (account.getId() == null) {
            throw new BadRequestException("账户不存在=>" + accountId);
        }
        if (StringUtils.isEmpty(account.getUsername()) || StringUtils.isEmpty(account.getPassword())) {
            throw new BadRequestException("账户信息不完整=>" + accountId);
        }
        SignInLog signInLog = new SignInLog();
        signInLog.setUsername(account.getUsername());
        signInLog.setNickName(account.getNickName());
        signInLog.setSuccess(false);
        try {
            String cookie = fytxService.login(account);
            if (cookie == null) {
                res.put("success", false);
                res.put("msg", "登录失败！请检查账户密码是否正确");
                signInLog.setDetail(res.getString("msg"));
                saveLog(JSONObject.toJSONString(signInLog));
                return res;
            }
            signInLog.setCookie(cookie);
            String formHash = fytxService.resolveFormHash(cookie);
            if (formHash == null) {
                res.put("success", false);
                res.put("msg", "登录成功，但formHash获取失败");
                signInLog.setDetail(res.getString("msg"));
                saveLog(JSONObject.toJSONString(signInLog));
                return res;
            }
            signInLog.setFormHash(formHash);
            SignInResultDto signInResultDto = fytxService.signIn(cookie, formHash);
            if (signInResultDto.isSuccess()) {
                res.put("success", true);
                res.put("msg", "签到成功！");
                signInLog.setSuccess(true);
                signInLog.setDetail(signInResultDto.getDetail());
                saveLog(JSONObject.toJSONString(signInLog));
                return res;
            }else {
                res.put("success", false);
                res.put("msg", signInResultDto.getDetail());
                signInLog.setDetail(res.getString("msg"));
                saveLog(JSONObject.toJSONString(signInLog));
                return res;
            }
        }catch (Exception e){
            e.printStackTrace();
            if (res.getBoolean("success") != null) {
                if (res.getString("msg") == null) {
                    res.put("msg", e.getMessage());
                    signInLog.setDetail(res.getString("msg"));
                    saveLog(JSONObject.toJSONString(signInLog));
                }
            }
        }
        return res;
    }

    @Override
    public Map<String,Object> queryAll(AccountQueryCriteria criteria, Pageable pageable) {
        Page<Account> page = accountRepository.findAll(pageable);
//        Page<Account> page = accountRepository.findAll((root, criteriaQuery, cb) -> {
//            List<Predicate> list = new ArrayList<>();
//            Path<Object> name = root.get("username");
//            list.add(cb.equal(name, "ljl"));
//            int size = list.size();
//            return cb.and(list.toArray(new Predicate[size]));
//        },pageable);
        return PageUtil.toPage(page);
    }

    @Override
    public List<Account> queryAll() {
        return accountRepository.findAll();
    }

    @Override
    public Account create(Account account) {
        return accountRepository.save(account);
    }

    @Override
    public Account update(Account account) {
        if (account.getId() == null) {
            throw new BadRequestException("账户id不能为空");
        }
        return accountRepository.save(account);
    }

    @Override
    public void deleteById(Long id) {
        accountRepository.deleteById(id);
    }

    @Override
    public void deleteAll(Set<Long> ids) {
        for (Long id : ids) {
            accountRepository.deleteById(id);
        }
    }

    private void saveLog(String signInLogStr) {
        ThreadUtil.execute(() -> {
            SignInLog signInLog = JSONObject.parseObject(signInLogStr, SignInLog.class);
            signInLogService.create(signInLog);
        });
    }
}
